#include "node.hpp"

int Node::size;
int Node::maxMoves;

Node::Node(const std::vector< std::pair<int,int> > &state,int n,int k,int m){
	queens = state;
	size = n;
	maxMoves = k;
	moves = m;
	conflicts = 0;
	h = 0;
	done = false;
	for(int i=0;i<size;i++){
		nconfl.push_back(0);
	}
	countConflicts();
	_h();
}

Node::Node(const std::vector< std::pair<int,int> > &state,int m){
	queens = state;
	moves = m;
	conflicts = 0;
	h = 0;
	done = false;
	for(int i=0;i<size;i++){
		nconfl.push_back(0);
	}
	countConflicts();
	_h();
}

void Node::move(int queen,int direction){
	queens[queen].first += direction;
	conflicts = 0;
	countConflicts();
	_h();
}

void Node::expand(std::vector<Node*> &list){
	createChildrenList();
	addChildren(list);
}

void Node::_h(){
	for(std::vector<int>::iterator i=nconfl.begin();i!=nconfl.end();i++){
		if(*i > 0){
			h++;
		}
	}
}

void Node::countConflicts(){
	int n=0;
	for(std::vector< std::pair<int,int> >::iterator i=queens.begin();i!=queens.end();i++){
		for(std::vector< std::pair<int,int> >::iterator j=i+1;j!=queens.end();j++){
			if(i->first==j->first || std::abs(i->first-j->first)==std::abs(i->second-j->second)){
				nconfl[n]++;
				conflicts++;
			}
		}
		n++;
	}
}

void Node::createChildrenList(){
	for(unsigned int i=0;i<queens.size();i++){
		if(queens[i].first > 1){
			children.push_back(Node(queens,moves+1));
			children.back().move(i,-1);
		}
		if(queens[i].first < size){
			children.push_back(Node(queens,moves+1));
			children.back().move(i,1);
		}
	}
}

void Node::addChildren(std::vector<Node*> &list){
	for(std::vector<Node>::iterator i=children.begin();i!=children.end();i++){
		//change to i->moves + h <= maxMoves if you want to find ONLY complete solutions
		if(i->moves <= maxMoves && !(i->done)){
			list.push_back(&(*i));
		}
		else{
			i->done = true;
		}
	}
}